﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SampleApplication
{
    public partial class Form1 : Form
    {
        HookTestForm htf;
        public Point mouseEventPoint;
        public MouseButtons mouseButton;
        private enumButtons buttonToClick = enumButtons.none;
        private enumInteractionMethod interactionMethod = enumInteractionMethod.Touch;
        //private enumInteractionMethod interactionMethod = enumInteractionMethod.Click;

        public enum enumInteractionMethod
        {
            Click,
            Touch
        }

        public enum enumButtons
        {
            none,
            left,
            right,
            doubleClick
        }

        //TODO: fix all of these hacks!

        private String[] mouseActions = 
        {
            "Left Click",
            "Right Click",
            "Double (Left) Click",
            "Mouse Down (Left)",
            "Mouse Up (Left)"
        };

        private MouseButtons[] mouseButtons =
        {
            MouseButtons.Left,
            MouseButtons.Right,
            MouseButtons.Left,
            MouseButtons.Left,
            MouseButtons.Left
        };


        private void InitForm()
        {
            buttonToClick = enumButtons.none;
            btnLeft.BackColor = System.Drawing.SystemColors.Control;
            btnRight.BackColor = System.Drawing.SystemColors.Control;
            btnDoubleClick.BackColor = System.Drawing.SystemColors.Control;
        }

        private MouseButtons currentButton;
        private int currentMouseActionIndex = 0;

        public Form1(HookTestForm htf, Point mouseEventPoint, MouseButtons mouseButton)
        {
            InitializeComponent();
            this.htf = htf;
            this.mouseEventPoint = mouseEventPoint;
            this.mouseButton = mouseButton;
            //htf.mouseHook.Stop();

            //make only background of form transparent
            //Ref: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.transparencykey.aspx
            this.BackColor = Color.LightCoral;
            this.TransparencyKey = this.BackColor;

            //populate mouseActions
            for (int i = 0; i < mouseActions.Length; i++)
            {
                this.mouseActionsComboBox.Items.Add(mouseActions[i]);
            }

        }

        private void btnNo_MouseEnter(object sender, EventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Touch)
            {
                SelectCancel();
            }
        }


        private void btnNo_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Click)
            {
                SelectCancel();
            }
        }

        private void SelectCancel()
        {
            Console.WriteLine("Right click NOT sent.");
            this.Hide();
            //this.Close();
            //htf.mouseHook.Start(); //its okay that this call is after the close call

            htf.gestureFormShown = false;
            InitForm();
        }







        private void btnYes_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Click)
            {
                this.performMouseAction();
            }
        }

        private void btnYes_MouseEnter(object sender, EventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Touch)
            {
                this.performMouseAction();
            }
        }

        private void performMouseAction()
        {
            //don't perfom an action unless a mouse action has been selected
            if (this.buttonToClick != enumButtons.none)
            {
                //hide the form before sending the click
                //so that the form does not capture it
                this.Hide();

                Point mouseScreenPt = this.mouseEventPoint;

                //move cursor to action point
                MouseKeyboardLibrary.MouseSimulator.X = mouseScreenPt.X;
                MouseKeyboardLibrary.MouseSimulator.Y = mouseScreenPt.Y;

                switch (this.buttonToClick)
                {
                    case enumButtons.left: MouseKeyboardLibrary.MouseSimulator.Click(MouseButtons.Left);
                        break;
                    case enumButtons.right: MouseKeyboardLibrary.MouseSimulator.Click(MouseButtons.Right);
                        break;
                    case enumButtons.doubleClick: MouseKeyboardLibrary.MouseSimulator.DoubleClick(MouseButtons.Left);
                        break;
                    /*case 3: MouseKeyboardLibrary.MouseSimulator.MouseDown(MouseButtons.Left);
                        break;
                    case 4: MouseKeyboardLibrary.MouseSimulator.MouseUp(MouseButtons.Left);
                        break;*/
                    case enumButtons.none:
                        Console.WriteLine("none button, escaping");
                        return;
                    default:
                        Console.WriteLine("default case, escaping");
                        return;
                    //break;
                }

                htf.gestureFormShown = false;
                InitForm();
            }//end check for none button
        }

        private void Form1_MouseLeave(object sender, EventArgs e)
        {
            //if the cursor leaves the form, reset the flag
            //so that clicks are still blocked
            
            //TODO: this does not handle the case when the cursor
            //is inside the form but inside of the button
            //that is still considered leaving
            //see HideFormTest for a solution

            Point cursorPos = Cursor.Position;
            Point formStartPt = this.Location;//this.PointToScreen(this.panel1.Location);
            Point formEndPt = new Point(formStartPt.X + this.Width, formStartPt.Y + this.Height);

            Console.WriteLine("formStart: " + formStartPt);
            Console.WriteLine("formEnd: " + formEndPt);

            //Point formEndPt = this.PointToScreen(
            //    new Point(this.panel1.Location.X + this.panel1.Width, this.panel1.Location.Y + this.panel1.Height));

            if (cursorPos.X < formStartPt.X
                || cursorPos.Y < formStartPt.Y
                || cursorPos.X >= formEndPt.X //TODO: should it be > or >=? 
                || cursorPos.Y >= formEndPt.Y)
            {
                this.htf.gestureFormShown = false;

                //this is actually annoying, because the path you take may actually go outside of
                //the form
                //this.Hide(); 

                
            }

            


        }

        private void mouseActionsComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.currentMouseActionIndex = this.mouseActionsComboBox.SelectedIndex;
            this.mouseActionsLabel.Text = mouseActions[currentMouseActionIndex];
        }

        private void btnLeft_MouseEnter(object sender, EventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Touch)
            {
                SelectLeft();
            }
        }

        private void btnLeft_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Click)
            {
                SelectLeft();
            }
        }

        //Select the left mouse button
        private void SelectLeft()
        {
            if (buttonToClick != enumButtons.doubleClick)
            {
                buttonToClick = enumButtons.left;
                btnLeft.BackColor = Color.LightGreen;
            }
        }

        private void btnRight_MouseEnter(object sender, EventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Touch)
            {
                SelectRight();
            }
        }

        private void btnRight_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Click)
            {
                SelectRight();
            }
        }

        //Select the right mouse button
        private void SelectRight()
        {
            buttonToClick = enumButtons.right;
            btnRight.BackColor = Color.LightGreen;
        }

        private void btnDoubleClick_MouseEnter(object sender, EventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Touch)
            {
                SelectDoubleClick();
            }
        }

        private void btnDoubleClick_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.interactionMethod == enumInteractionMethod.Click)
            {
                SelectDoubleClick();
            }
        }

        private void SelectDoubleClick()
        {
            if (buttonToClick == enumButtons.left)
            {
                buttonToClick = enumButtons.doubleClick;
                btnDoubleClick.BackColor = Color.LightGreen;
            }
        }

        public void drawCircleAtMouseEventPoint()
        {
            Graphics graphics = this.CreateGraphics();
            int radius = 50;

            Point mouseEventPointClient = this.PointToClient(this.mouseEventPoint);
            
            Pen pen = new Pen(Color.Green, 5);

            Rectangle rectangle = new Rectangle(mouseEventPointClient.X - radius,
                mouseEventPointClient.Y - radius, 2*radius, 2*radius);

            graphics.Clear(this.BackColor);
            graphics.DrawEllipse(pen, rectangle);
            graphics.DrawLine(pen, new Point(rectangle.X + rectangle.Width / 2, rectangle.Y), 
                new Point(rectangle.X + rectangle.Width/2, rectangle.Y + rectangle.Height));
            graphics.DrawLine(pen, new Point(rectangle.X, rectangle.Y + rectangle.Height/2),
                new Point(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height/2));


            graphics.DrawRectangle(pen, 
                0, 0, 
                this.Width, 
                this.Height);
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            drawCircleAtMouseEventPoint();
        }


    }
}
